#include "vroute_data_in_outter.hpp"
#include "logger.hpp"
#include "vroute_sys.hpp"
#include "vroute_tools.hpp"

namespace vroute_stack
{
    class CTestDataInO
    {
    public:
        static CTestDataInO* CTestDataInO::getInstance()
        {
            if(nullptr == _instance)
            {
                _instance = new CTestDataInO();
            }
            return _instance;
        }

        static void CTestDataInO::releaseInstance()
        {
            if(nullptr != _instance)
            {
                delete _instance;
                _instance = nullptr;
            }
        }

    private:
        CTestDataInO()
        {
            cdin = CDataInOutter::getInstance();
            cdin->init();
        }

        ~CTestDataInO()
        {
            if (cdin != nullptr)
            {
                CDataInOutter::releaseInstance();
                cdin = nullptr;
            }
        }

    public:
        void startWork()
        {
            char* buffer128 = new char[110];
            char* buffer512 = new char[500];
            char* buffer1024 = new char[1000];
            char* buffer2048 = new char[2030];
            char* buffer4096 = new char[4080];
            while (true)
            {
                // 128
                memset(buffer128, 0x00, 110);
                CTools::fillArrayRadom((unsigned char*)buffer128, 110);
                cdin->dataIn(buffer128, 110);

                // 512
                memset(buffer128, 0x00, 500);
                CTools::fillArrayRadom((unsigned char*)buffer512, 500);
                cdin->dataIn(buffer128, 500);

                // 1024
                memset(buffer128, 0x00, 1000);
                CTools::fillArrayRadom((unsigned char*)buffer1024, 1000);
                cdin->dataIn(buffer128, 1000);

                // 2048
                memset(buffer128, 0x00, 2030);
                CTools::fillArrayRadom((unsigned char*)buffer2048, 2030);
                cdin->dataIn(buffer128, 2030);

                // 4096
                memset(buffer128, 0x00, 4080);
                CTools::fillArrayRadom((unsigned char*)buffer4096, 4080);
                cdin->dataIn(buffer128, 4080);
            }
        }

    protected:
        CDataInOutter* cdin;
        static CTestDataInO* _instance;
    };

    CTestDataInO* CTestDataInO::_instance = nullptr;

    DWORD WINAPI threadEntryTpIn(LPVOID p)
    {
        logger_info("void dataFromOuterToOuter()");
        CTestDataInO* ins = CTestDataInO::getInstance();
        ins->startWork();
        CTestDataInO::releaseInstance();
        ins = nullptr;
        return 0;
    }

    void dataFromOuterToOuter()
    {
        CTestDataInO* ins = CTestDataInO::getInstance();   
        
        HANDLE hthread[4];
        for (int i=0; i<4; ++i)
        {
            vroute_createThread(hthread[i], threadEntryTpIn, nullptr);
        }
        WaitForMultipleObjects(4, hthread, true, INFINITE);
        CTestDataInO::releaseInstance();
        ins = nullptr;
        return;
    }
}